/*
 * 创建日期 2006-9-19
 *
 * 更改所生成文件模板为
 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
package com.vanda.report.dp;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.vanda.report.ReportData;
import com.vanda.report.ReportException;
import com.vanda.report.ReportInnerData;
import com.vanda.report.ReportRow;
import com.vanda.report.Validation;
import com.vanda.report.element.BeanElement;
import com.vanda.util.LogFunc;


/**
 * @author amway
 *
 * 更改所生成类型注释的模板为
 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
public class MountElement extends BeanElement {
	//待处理的数据,如果有多个,按","分隔
	private String data_src;
	//行对应属性名称
	private String row_property;
	//列对应属性名称
	private String col_property;
	//行对应属性值,多个按","分隔
	private String row_value ;
	//列对应属性值,多个按","分隔
	private String col_value;
	//保存组织后的数据
	private String result_property = "reportList";
	//
	private String default_value = "";
	//如果一行都是null,是否显示，true-显示，false-不显示
	private String need_null = "true";
	
	//内部属性
	private String colName = "col";	//列属性名称
	
	/**
	 * 校验标签
	 */
	public void validator() throws ReportException {
		Validation.checkRequired("MountElement","data_src",data_src);
		Validation.checkRequired("MountElement","row_property",row_property);
		Validation.checkRequired("MountElement","col_property",col_property);
		//显示值属性
		Validation.checkRequired("MountElement","property",super.getProperty());
		Validation.checkRequired("MountElement","row_value",row_value);
		Validation.checkRequired("MountElement","col_value",col_value);
	}

	/**
	 * 标签执行方法，递归执行
	 * @param obj
	 */
	public void execute(Object obj) throws ReportException {
		ReportInnerData reportData = (ReportInnerData) obj;

		try {
			//取得上下文数据
			Object contextObj = super.getNameObject(reportData);
			//分解数据
			String[] dataSrcs = data_src.split(",");
			String[] rowValues = row_value.split(",");
			String[] colValues = col_value.split(",");
			String[] showPropertys = super.getProperty().split(",");
			String[] defaultValues = null;
			boolean needNull = true;
			if(need_null != null && need_null.equals("false")){
				needNull = false;
			}
			
			String[] strs = default_value.split(",");
			if(showPropertys.length > strs.length){
				defaultValues = new String[showPropertys.length];
				for(int i=0;i<defaultValues.length;i++){
					if(i < strs.length)
						defaultValues[i] = strs[i];
					else
						defaultValues[i] = "";
				}
			}else{
				defaultValues = strs;
			}
			HashMap rowMap = new HashMap();
			
			for(int i=0;i<dataSrcs.length;i++){
				Object dataSrc = super.getProperty(contextObj,dataSrcs[i]);
				//组装数据
				mountData(rowMap,dataSrc,showPropertys);
			}
			
			List resultList = new ArrayList(rowValues.length);
			for(int i=0;i<rowValues.length;i++){
				ReportRow oneRow = new ReportRow();
				boolean isNull = true;
				for(int j=0;j<colValues.length;j++){
					//String key = getKey(rowValues[i],colValues[j]);
					Object[] values = getValues(rowValues[i],colValues[j],rowMap);
					
					
					if(values == null){
						values = new Object[showPropertys.length];
					}else{
						isNull = false;
					}
					for(int k=0;k<values.length;k++){
						if(values[k] == null){
							values[k] = defaultValues[k];
						}
						if(values.length > 1){
							oneRow.put(colName+j+k,values[k]);
						}else{
							oneRow.put(colName+j,values[k]);
						}
					}
					
				}
				
				//如果需要显示空值或此行不是空值，则保存
				if(needNull == true || isNull == false){
					resultList.add(oneRow);
				}
			}
			
			//将处理后的list放入result_property
			super.setProperty(reportData,result_property,resultList);
			
			//递规执行方法
			super.execute(obj);
		} catch (ReportException e) {
			throw e;
		} catch (Exception e) {
			throw new ReportException(e);
		}
	}
	
	private Object[] getValues(String rowValue,String colValue,HashMap rowMap){
		rowValue = rowValue.replace('|',',');
		colValue = colValue.replace('|',',');
		String[] rowValues = rowValue.split(",");
		String[] colValues = colValue.split(",");
		
		Object[] values = null;
		for(int i=0;i<rowValues.length;i++){
			for(int j=0;j<colValues.length;j++){
				String key = getKey(rowValues[i],colValues[j]);
				if(values == null){
					values = (Object[])rowMap.get(key);
				}else{
					Object[] tmpValues = (Object[])rowMap.get(key);
					add(values,tmpValues);
				}
			}
		}
		return values;
	}
	
	/**
	 * 相加,values1+valus2=>values1,数字则做加法,字符串做连接
	 * @param values1
	 * @param values2
	 */
	private void add(Object[] values1,Object[] values2){
		if(values2 == null){
			return;
		}
		for(int i=0;i<values1.length;i++){
			values1[i] = addValue(values1[i],values2[i]);
		}
	}
	
	private Object addValue(Object value1,Object value2){
		Object obj1 = getNumberOrString(value1);
		Object obj2 = getNumberOrString(value2);
		
		if(obj1 instanceof String){
			return obj1.toString() + obj2.toString();
		}
		
		return ((BigDecimal)obj1).add((BigDecimal)obj2);
	}
	
	private Object getNumberOrString(Object value){
		String str = value.toString();
		try{
			BigDecimal bg = new BigDecimal(str);
			return bg;
		}catch(Exception e){
			
		}
		return str;
	}
	
	
	
	private void mountData(HashMap rowMap,Object oneData,String[] showPropertys) throws Exception{
		//如果是List,则循环组装
		if(oneData instanceof List){
			List lstData = (List)oneData;
			for(int i=0;i<lstData.size();i++){
				Object data = lstData.get(i);
				mountData(rowMap,data,showPropertys);
			}
			return;
		}
		
		//取得行属性值
		Object rowValue = super.getProperty(oneData,row_property);
		//取得列属性值
		Object colValue = super.getProperty(oneData,col_property);
		//取得显示的属性值
		Object[] showValues = new Object[showPropertys.length];
		for(int i=0;i<showPropertys.length;i++){
			showValues[i] = super.getProperty(oneData,showPropertys[i]);
		}
		
		String key = getKey(rowValue,colValue);
		
		rowMap.put(key,showValues);
	}
	
	private String getKey(Object rowValue,Object colValue){
		return rowValue.toString()+":"+colValue.toString();
	}
	
	/**
	 * @return
	 */
	public String getCol_property() {
		return col_property;
	}

	/**
	 * @return
	 */
	public String getCol_value() {
		return col_value;
	}

	/**
	 * @return
	 */
	public String getData_src() {
		return data_src;
	}

	/**
	 * @return
	 */
	public String getResult_property() {
		return result_property;
	}

	/**
	 * @return
	 */
	public String getRow_property() {
		return row_property;
	}

	/**
	 * @return
	 */
	public String getRow_value() {
		return row_value;
	}

	/**
	 * @param string
	 */
	public void setCol_property(String string) {
		col_property = string;
	}

	/**
	 * @param string
	 */
	public void setCol_value(String string) {
		col_value = string;
	}

	/**
	 * @param string
	 */
	public void setData_src(String string) {
		data_src = string;
	}

	/**
	 * @param string
	 */
	public void setResult_property(String string) {
		result_property = string;
	}

	/**
	 * @param string
	 */
	public void setRow_property(String string) {
		row_property = string;
	}

	/**
	 * @param string
	 */
	public void setRow_value(String string) {
		row_value = string;
	}
	/**
	 * @return
	 */
	public String getDefault_value() {
		return default_value;
	}

	/**
	 * @param string
	 */
	public void setDefault_value(String string) {
		default_value = string;
	}

	public static void main(String[] args){
		/*MountElement mount = new MountElement();
		List list1 = new ArrayList();
		ReportRow row = new ReportRow();
		
		row.put("ordertype","1");
		row.put("paytype","A");
		row.put("amount",new java.math.BigDecimal("872387.53"));
		row.put("num","1");
		list1.add(row);
		
		row = new ReportRow();
		row.put("ordertype","1");
		row.put("paytype","B");
		row.put("amount",new java.math.BigDecimal("12722.94"));
		row.put("num","2");
		list1.add(row);
		
		row = new ReportRow();
		row.put("ordertype","1");
		row.put("paytype","C");
		row.put("amount",new java.math.BigDecimal("11836"));
		row.put("num","3");
		list1.add(row);
		
		row = new ReportRow();
		row.put("ordertype","1");
		row.put("paytype","D");
		row.put("amount",new java.math.BigDecimal("500"));
		row.put("num","4");
		list1.add(row);
		
		row = new ReportRow();
		row.put("ordertype","1");
		row.put("paytype","F");
		row.put("amount",new java.math.BigDecimal("750"));
		row.put("num","5");
		list1.add(row);
		
		row = new ReportRow();
		row.put("ordertype","1");
		row.put("paytype","G");
		row.put("amount",new java.math.BigDecimal("9276.66"));
		row.put("num","6");
		list1.add(row);
		
		row = new ReportRow();
		row.put("ordertype","1");
		row.put("paytype","Q");
		row.put("amount",new java.math.BigDecimal("3932"));
		row.put("num","7");
		list1.add(row);
		
		row = new ReportRow();
		row.put("ordertype","2");
		row.put("paytype","A");
		row.put("amount",new java.math.BigDecimal("35570.8"));
		row.put("num","8");
		list1.add(row);
		
		row = new ReportRow();
		row.put("ordertype","2");
		row.put("paytype","B");
		row.put("amount",new java.math.BigDecimal("100"));
		row.put("num","9");
		list1.add(row);
		
		row = new ReportRow();
		row.put("ordertype","2");
		row.put("paytype","C");
		row.put("amount",new java.math.BigDecimal("62.66"));
		row.put("num","10");
		list1.add(row);
		
		row = new ReportRow();
		row.put("ordertype","2");
		row.put("paytype","G");
		row.put("amount",new java.math.BigDecimal("18.67"));
		row.put("num","11");
		list1.add(row);
		
		row = new ReportRow();
		row.put("ordertype","6");
		row.put("paytype","B");
		row.put("amount",new java.math.BigDecimal("1813.3"));
		row.put("num","12");
		list1.add(row);
		
		row = new ReportRow();
		row.put("ordertype","9");
		row.put("paytype","A");
		row.put("amount",new java.math.BigDecimal("3015.99"));
		row.put("num","13");
		list1.add(row);
		
		row = new ReportRow();
		row.put("ordertype","9");
		row.put("paytype","C");
		row.put("amount",new java.math.BigDecimal("137.34"));
		row.put("num","14");
		list1.add(row);
		
		ReportData reportData = new ReportData();
		reportData.setReportList(list1);
		mount.setData_src("reportList");
		mount.setRow_property("paytype");
		mount.setCol_property("ordertype");
		mount.setRow_value("A,B,C,D,F,G,Q");
		mount.setCol_value("1,2,6,9");
		mount.setDefault_value("0.00,0");
		mount.setProperty("amount,num");
		try{
			ReportInnerData inData = new ReportInnerData(reportData);
			inData.setContextData(reportData);
			mount.execute(inData);
			
			List reportList = inData.getReportList();
			String[] rowvalues = mount.getRow_value().split(",");
			for(int i=0;i<reportList.size();i++){
				ReportRow oneRow = (ReportRow)reportList.get(i);
				
				System.out.print(rowvalues[i]+"\t");
				for(int j=0;j<4;j++){
					for(int k=0;k<2;k++){
						System.out.print(oneRow.get("col"+j+k)+"\t\t");
					}
					
				}
				LogFunc.info("");
			}
		}catch(Exception e){
			e.printStackTrace();
		}*/
		
		String str = "abcc";
		String strs = str.replace('|',',');
		
		System.out.println(strs);
	}
		
	/**
	 * @return
	 */
	public String getColName() {
		return colName;
	}

	/**
	 * @return
	 */
	public String getNeed_null() {
		return need_null;
	}

	/**
	 * @param string
	 */
	public void setColName(String string) {
		colName = string;
	}

	/**
	 * @param string
	 */
	public void setNeed_null(String string) {
		need_null = string;
	}

}
